


trait Device {
    fn is_enable(&self) -> bool;
    fn disable(&mut self);
    fn enable(&mut self);

    fn get_volume(&self) -> usize ;
    fn set_volume(&mut self, volume: usize);


}
trait RemoteControl<D> 
where D: Device
{
    fn device(&self) -> &D;
    fn device_mut(&mut self) -> &mut D;

    fn toggle_power(&mut self) {
        println!("toggle power before, status:{}", self.device().is_enable());
        if self.device().is_enable() {
            self.device_mut().disable();
        }
        else{
            self.device_mut().enable();
        }
        println!("toggle power status: {}", self.device().is_enable());
    }

    fn volume_down(&mut self) {
        let volume = self.device().get_volume();
        println!("volume down before: {}", volume);
        if volume >= 10 {
            self.device_mut().set_volume(volume - 10);
        }
        else{
            self.device_mut().set_volume(0);
        }
        println!("volume down after: {}", self.device().get_volume());
    }
    fn volume_up(&mut self) {
        let volume = self.device().get_volume();
        println!("volume up before: {}", volume);
        self.device_mut().set_volume(volume + 10);
        println!("volume up after: {}", self.device().get_volume());
    }
}

#[derive(Debug)]
struct Tv {
    enable: bool,
    volume: usize,
}
impl Default for Tv {
    fn default() -> Self {
        Self {
            enable: false,
            volume: 10,
        }
    }
}

impl Device for Tv {
    fn is_enable(&self) -> bool{
        self.enable
    }
    fn disable(&mut self){
        self.enable = false;
    }
    fn enable(&mut self){
        self.enable = true;
    }
    fn get_volume(&self) -> usize {
        self.volume
    }
    fn set_volume(&mut self, volume: usize) {
        self.volume = volume;
    }
}

struct Radio {
    enable: bool,
    volume: usize,
}
impl Default for Radio {
    fn default() -> Self {
        Self {
            enable: false,
            volume: 10,
        }
    }
}

impl Device for Radio {
    fn is_enable(&self) -> bool{
        self.enable
    }
    fn disable(&mut self){
        self.enable = false;
    }
    fn enable(&mut self){
        self.enable = true;
    }
    fn get_volume(&self) -> usize {
        self.volume
    }
    fn set_volume(&mut self, volume: usize) {
        self.volume = volume;
    }
}

struct MyRemoteControl<D>
where D: Device
 {
    device: D,
}
impl<D> MyRemoteControl<D> 
where D: Device
{
    fn new(device: D) -> Self {
        Self {
            device
        }
    }
}

impl<D> RemoteControl<D> for MyRemoteControl<D>
where D: Device
{
    fn device(&self) -> &D {
        & self.device
    }
    fn device_mut(&mut self) -> &mut D {
        &mut self.device
    }
} 

struct AdvanceRemoteControl<D> 
where D: Device
{
    device: D,
}

impl<D> RemoteControl<D> for AdvanceRemoteControl<D> 
where D: Device 
{
    fn device(&self) -> &D {
        & self.device
    } 
    fn device_mut(&mut self) -> &mut D {
       &mut self.device 
    }
}
impl<D> AdvanceRemoteControl<D> 
where D: Device  
{
    fn new(device: D) -> Self {
        Self {
            device
        }
    }
    fn mute(&mut self) {
        println!("mute before: {}", self.device().get_volume());
        self.device_mut().set_volume(0);
        println!("mute after: {}", self.device().get_volume());
    }
}

#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn test_main(){
        let mut remote = MyRemoteControl::new(Tv::default());
        remote.toggle_power();
        remote.volume_up();
        remote.volume_up();
        remote.volume_down();

        let mut rc = AdvanceRemoteControl::new(Radio::default());
        rc.mute();
    }
}



